package Core;

public class Tween implements Runnable
{
    // флаги и константы
    public static final int LINEAR=0;
    private static final long MinDelay=3;
    private volatile boolean paused=false;
    private volatile boolean blocked=false;
    private long oldTime=0;

    // переменные
    private double value, target, start;
    private long tasktime, timeleft, starttime=0;
    private int func;

    // поток
    private Thread thread;

    // интерфейсы
    private TweenInterface object;


    // конструкторы
    public Tween(TweenInterface o, long ttime)
    {
        value = target = 0;
        func = LINEAR;
        tasktime = ttime;
        object = o;

        initThread();
    }

    public Tween(TweenInterface o, long ttime, int f)
    {
        tasktime = ttime;
        func = f;
        object = o;

        initThread();

    }

    public Tween(TweenInterface o, long ttime, int f, double v, double t)
    {
        value = start = v;
        target = t;
        tasktime = ttime;
        func = f;
        object = o;

        System.out.println("Set tween from "+value+" to "+target);

        initThread();

    }

    // инициализация потока
    void initThread()
    {
        thread = new Thread(this);
        thread.setPriority(Thread.MIN_PRIORITY);
    }

    // гет-сет
    public double getValue()
    {
        return value;
    }
    public void setTarget(double d)
    {
        target = d;
    }

    // функция потока
    public void run()
    {
        oldTime=starttime=System.currentTimeMillis();

        while(!paused)
        {
            long t = System.currentTimeMillis();
            long dt = t - oldTime;

            if(dt >= MinDelay && !blocked)
            {
                //System.out.println("Tick!");
                
                if(t-starttime > tasktime)
                {
                    value = target;

                    System.out.println("Set value to "+value);
                    
                    object.tweenTick(this);

                    block();
                }
                else
                {
                    value = ((double)(target - start)/tasktime) * (t-starttime);
                    
                    object.tweenTick(this);
                }

                oldTime =  System.currentTimeMillis();
            }
        }
    }

    // обработка потока
    public void enable()
    {
        paused = false;

        if(!thread.isAlive()) thread.start();
    }

    public void disable()
    {
        paused = true;
    }

    public void block()
    {
        blocked = true;
    }

    public void release()
    {
        blocked = false;
    }
}
